/*
 * @Author: venom
 * @Date: 2021-03-04 14:19:23
 * @LastEditors: venom
 * @LastEditTime: 2021-03-08 17:25:51
 * @Description: 专门存放参数的结构体
 * @FilePath: \venom-nacos-sdk\src\params.rs
 * MIT
 */

use reqwest::multipart;
use reqwest::multipart::Form;


#[derive(Debug)]
pub struct Params {
    pub query: String,
    pub forms: Form,
}


#[derive(Default, Clone)]
pub struct ConfigBuilder {
    tenant: String,
    dataId: String,
    group: String,
    content: Option<String>,
    Type: Option<String>,
}

impl ConfigBuilder {
    // 属性定制方法。消耗原本的构建器，修改属性后重新生成新构建器

    pub fn set_tenant(mut self, tenant: String) -> Self {
        self.tenant = tenant;
        self
    }

    pub fn set_dataId(mut self, dataId: String) -> Self {
        self.dataId = dataId;
        self
    }

    pub fn set_group(mut self, group: String) -> Self {
        self.group = group;
        self
    }

    pub fn set_content(mut self, content: String) -> Self {
        self.content = Some(content);
        self
    }

    pub fn set_type(mut self, ctype: String) -> Self {
        self.Type = Some(ctype);
        self
    }

    fn params_format_query(&self) -> String {
        let mut query = String::new();
        let temp = format!(
            "?tenant={}&dataId={}&group={}",
            &self.tenant, &self.dataId, &self.group
        );
        query.push_str(temp.as_str());

        match &self.content {
            Some(content) => query.push_str(format!("&content={}", content).as_str()),
            None => (),
        };

        match &self.Type {
            Some(ctype) => query.push_str(format!("&type={}", ctype).as_str()),
            None => (),
        };
        return query;
    }

    pub fn params_format_form(&self) -> multipart::Form {
        let form = multipart::Form::new()
            .text("dataId", self.dataId.clone())
            .text("tenant", self.tenant.clone())
            .text("group", self.group.clone());

        let form = match self.content.clone() {
            Some(content) => form.text("content", content),
            None => form,
        };

        let form = match self.Type.clone() {
            Some(ctype) => form.text("type", ctype),
            None => form,
        };
        return form;
    }

    /**
     * @description: 最后通过 `build` 方法生成所需类型
     * @param {*} self
     * @return {*}
     */
    pub fn build(self) -> Result<Params, &'static str> {
        //必填项的检验
        if self.tenant.is_empty() { return Err("tenant not allow Empty"); }
        if self.group.is_empty() { return Err("group not allow Empty"); }
        if self.dataId.is_empty() { return Err("data not allow Empty"); }
        let query = self.params_format_query();
        let forms = self.params_format_form();

        Ok(
            Params {
                query: query,
                forms: forms,
            }
        )
    }
}


#[derive(Default, Clone)]
pub struct InstanceBuilder {
    serviceName: String,
    ip: String,
    port: i32,
    namespaceId: Option<String>,
    weight: Option<f32>,
    enabled: Option<bool>,
    healthy: Option<bool>,
    metadata: Option<String>,
    clusterName: Option<String>,
    groupName: Option<String>,
    ephemeral: Option<bool>,
}

impl InstanceBuilder {
    pub fn set_serviceName(mut self, serviceName: String) -> Self {
        self.serviceName = serviceName;
        self
    }
    pub fn set_ip(mut self, ip: String) -> Self {
        self.ip = ip;
        self
    }
    pub fn set_port(mut self, port: i32) -> Self {
        self.port = port;
        self
    }
    pub fn set_namespaceId(mut self, namespaceId: String) -> Self {
        self.namespaceId = Some(namespaceId);
        self
    }

    pub fn set_weight(mut self, weight: f32) -> Self {
        self.weight = Some(weight);
        self
    }
    pub fn set_enabled(mut self, enabled: bool) -> Self {
        self.enabled = Some(enabled);
        self
    }
    pub fn set_healthy(mut self, healthy: bool) -> Self {
        self.healthy = Some(healthy);
        self
    }
    pub fn set_metadata(mut self, metadata: String) -> Self {
        self.metadata = Some(metadata);
        self
    }
    pub fn set_clusterName(mut self, clusterName: String) -> Self {
        self.clusterName = Some(clusterName);
        self
    }
    pub fn set_groupName(mut self, groupName: String) -> Self {
        self.groupName = Some(groupName);
        self
    }

    pub fn set_ephemeral(mut self, ephemeral: bool) -> Self {
        self.ephemeral = Some(ephemeral);
        self
    }


    pub fn params_format_query(&self) -> String {
        let mut query = String::new();
        let temp = format!(
            "?serviceName={}&ip={}&port={}",
            &self.serviceName, &self.ip, &self.port
        );
        query.push_str(temp.as_str());

        match &self.namespaceId {
            Some(namespaceId) => query.push_str(format!("&namespaceId={}", namespaceId).as_str()),
            None => (),
        };

        match &self.weight {
            Some(weight) => query.push_str(format!("&weight={}", weight.to_string()).as_str()),
            None => (),
        };
        match &self.enabled {
            Some(enabled) => query.push_str(format!("&enabled={}", enabled).as_str()),
            None => (),
        };
        match &self.healthy {
            Some(healthy) => query.push_str(format!("&healthy={}", healthy).as_str()),
            None => (),
        };
        match &self.metadata {
            Some(metadata) => query.push_str(format!("&metadata={}", metadata).as_str()),
            None => (),
        };
        match &self.clusterName {
            Some(clusterName) => query.push_str(format!("&clusterName={}", clusterName).as_str()),
            None => (),
        };
        match &self.groupName {
            Some(groupName) => query.push_str(format!("&groupName={}", groupName).as_str()),
            None => (),
        };
        match &self.ephemeral {
            Some(ephemeral) => query.push_str(format!("&ephemeral={}", ephemeral).as_str()),
            None => (),
        };
        return query;
    }

    pub fn params_format_form(&self) -> multipart::Form {
        let form = multipart::Form::new()
            .text("dataId", self.serviceName.clone())
            .text("tenant", self.ip.clone())
            .text("group", self.port.clone().to_string());

        let form = match self.namespaceId.clone() {
            Some(namespaceId) => form.text("namespaceId", namespaceId),
            None => form,
        };
        let form = match self.weight.clone() {
            Some(weight) => form.text("weight", weight.to_string()),
            None => form,
        };
        let form = match self.enabled.clone() {
            Some(enabled) => form.text("enabled", enabled.to_string()),
            None => form,
        };
        let form = match self.healthy.clone() {
            Some(healthy) => form.text("healthy", healthy.to_string()),
            None => form,
        };
        let form = match self.metadata.clone() {
            Some(metadata) => form.text("metadata", metadata),
            None => form,
        };
        let form = match self.clusterName.clone() {
            Some(clusterName) => form.text("clusterName", clusterName),
            None => form,
        };
        let form = match self.groupName.clone() {
            Some(groupName) => form.text("groupName", groupName),
            None => form,
        };
        let form = match self.ephemeral.clone() {
            Some(ephemeral) => form.text("ephemeral", ephemeral.to_string()),
            None => form,
        };

        return form;
    }
}

#[derive(Default, Clone)]
pub struct ServiceBuilder {
    serviceName: String,
    groupName: Option<String>,
    namespaceId: Option<String>,
    protectThreshold: Option<f32>,
    metadata: Option<String>,
    selector: Option<String>,
}

impl ServiceBuilder {
    pub fn set_serviceName(mut self, serviceName: String) -> Self {
        self.serviceName = serviceName;
        self
    }
    pub fn set_groupName(mut self, groupName: String) -> Self {
        self.groupName = Some(groupName);
        self
    }
    pub fn set_namespaceId(mut self, namespaceId: String) -> Self {
        self.namespaceId = Some(namespaceId);
        self
    }
    pub fn set_protectThreshold(mut self, protectThreshold: f32) -> Self {
        self.protectThreshold = Some(protectThreshold);
        self
    }
    pub fn set_metadata(mut self, metadata: String) -> Self {
        self.metadata = Some(metadata);
        self
    }
    pub fn set_selector(mut self, selector: String) -> Self {
        self.selector = Some(selector);
        self
    }
    fn params_format_query(&self) -> String {
        let mut query = String::new();
        query.push_str(format!("?serviceName={}", self.serviceName).as_str());
        match &self.groupName {
            Some(groupName) => query.push_str(format!("&groupName={}", groupName).as_str()),
            None => (),
        };
        match &self.namespaceId {
            Some(namespaceId) => {
                query.push_str(format!("&namespaceId={}", namespaceId).as_str())
            }
            None => ()
        };
        match &self.protectThreshold {
            Some(protectThreshold) => {
                query.push_str(format!("&protectThreshold={}", protectThreshold).as_str())
            }
            None => ()
        };
        match &self.metadata {
            Some(metadata) => query.push_str(format!("&metadata={}", metadata).as_str()),
            None => ()
        };
        match &self.selector {
            Some(selector) => query.push_str(format!("&selector={}", selector).as_str()),
            None => (),
        };
        return query;
    }
    pub fn params_format_form(&self) -> multipart::Form {
        let form = multipart::Form::new();
        let form = form.text("serviceName", self.serviceName.clone());

        let form = match self.groupName.clone() {
            Some(groupName) => form.text("groupName", groupName),
            None => form,
        };
        let form = match self.namespaceId.clone() {
            Some(namespaceId) => form.text("namespaceId", namespaceId),
            None => form,
        };
        let form = match self.protectThreshold.clone() {
            Some(protectThreshold) => form.text("protectThreshold", protectThreshold.to_string()),
            None => form,
        };
        let form = match self.metadata.clone() {
            Some(metadata) => form.text("metadata", metadata),
            None => form,
        };
        let form = match self.selector.clone() {
            Some(selector) => form.text("selector", selector),
            None => form,
        };
        return form;
    }
    pub fn build(self) -> Result<Params, &'static str> {
        if self.serviceName.is_empty() {
            return Err("serviceName not allow Empty");
        }
        let query = self.params_format_query();
        let forms = self.params_format_form();
        Ok(Params {
            query: query,
            forms: forms,
        })
    }
}






pub mod url {
    pub const CONFIGS: &str = "/nacos/v1/cs/configs";
    pub const INSTANCE: &str = "/nacos/v1/ns/instance";
    pub const INSTANCE_LIST: &str = "/nacos/v1/ns/instance/list";
    pub const SERVICE: &str = "/nacos/v1/ns/service";
    pub const SERVICE_LIST: &str = "/nacos/v1/ns/service/list";
}